package com.mxchip.livestar

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI
import com.mxchip.livestar.av.camera.CameraHandle
import com.mxchip.livestar.av.camera.HDMIHandle
import com.mxchip.livestar.av.camera.WifiCamera
import com.mxchip.livestar.base.HideSystemUILifecycleAware
import com.mxchip.livestar.base.SystemData
import com.mxchip.livestar.base.toast
import com.mxchip.livestar.duobeiyun.pass.NetMap
import com.mxchip.livestar.original.SendAudioUtil
import com.mxchip.livestar.repository.RoomClientRepository
import com.mxchip.livestar.rx.RxBus
import com.mxchip.livestar.rx.RxConstant
import com.mxchip.livestar.ui.Call
import com.mxchip.livestar.ui.call.*
import com.mxchip.livestar.utils.*
import com.trello.lifecycle2.android.lifecycle.AndroidLifecycle
import com.trello.rxlifecycle3.LifecycleProvider
import com.videohigh.boegam.screenpush.ScreenPushManager
import com.videohigh.graham.*
import kotlinx.android.synthetic.main.activity_call_a.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList

/**
 * 通话界面
 */
class CallActivityA : AppCompatActivity(), Handler.Callback {

    private val provider: LifecycleProvider<Lifecycle.Event> = AndroidLifecycle.createLifecycleProvider(this)

    private lateinit var navController: NavController
    private lateinit var appBarConfiguration: AppBarConfiguration

    private val logger = FileLog.getLogger(CallActivityA::class.java)
    private val dbyViewModel by viewModels<DbyViewModel>()

    private val screenViewModel by viewModels<ScreenViewModel>()
    private val dbyNetworkViewModel by viewModels<DbyNetworkViewModel>()
    private val roomViewModel by viewModels<RoomViewModel>()

    // private val sampleSDK = SampleSDK.getInstance()


    private val handler: Handler by lazy {
        Handler(this)
    }
    private var mNetSpeedTimer: NetSpeedTimer? = null

    private val netMap: NetMap by lazy {
        NetMap(this)
    }

    private var checkBadNetWork = 0

    private val networkQualityListener = object : SDKNetworkQualityListener {

        var currentLevel = SystemData.networkLevelStandard
        var netDesc: StringBuilder = StringBuilder()
        var oldTime: Long = 0

        override fun onBandwidthAdvise(bwadv: Int, lostRate: Float) {

            Log.d("CallActivityA::onNetworkStatistics:Self",
                    "deviceName: bwadv:${bwadv} lostRate:${lostRate} ")
            if (bwadv == 0 && lostRate == 0.0f) return

            if (bwadv < SystemData.lowerBitRate || lostRate > 0.3) {
                currentLevel = SystemData.networkLevelMinimum

            } else if (bwadv < SystemData.middleBitRate || lostRate > 0.2) {
                currentLevel = SystemData.networkLevelLower

            } else if (bwadv < SystemData.standardBitRate || lostRate > 0.1) {
                currentLevel = SystemData.networkLevelMiddle

            } else if (bwadv > SystemData.standardBitRate || lostRate < 0.1) {
                currentLevel = SystemData.networkLevelStandard
            }

            screenViewModel.networkLevel(currentLevel)
        }

        override fun onDelay(delay: Int) {
            Log.d("CallActivity", "network-----onNetWorkDelay: $delay")

            lifecycleScope.launch {
                dbyNetworkViewModel.setDelay(delay)
            }
        }

        override fun onQuality(term: Term, txQuality: Int, rxQuality: Int) {
            if (System.currentTimeMillis() - oldTime < 200) {
                netDesc.append("id:$term\ntxQuality↑:${netMap.getTxQuality(txQuality)}\nrxQuality↓:${netMap.getRxQuality(rxQuality)}\n")
            } else {
                netDesc.clear()
                netDesc.append("id:$term\ntxQuality↑:${netMap.getTxQuality(txQuality)}\nrxQuality↓:${netMap.getRxQuality(rxQuality)}\n")
            }
            oldTime = System.currentTimeMillis()
            dbyViewModel.netQuality(netDesc.toString())
        }

        override fun onQuality(txQuality: Int, rxQuality: Int) {
            lifecycleScope.launch {
                dbyNetworkViewModel.setTxQuality(txQuality)
                dbyNetworkViewModel.setRxQuality(rxQuality)
            }
            if ((txQuality in 5..6 || rxQuality in 5..6)) {// && readyFinish.get()) {
                // modifyFinish.set(false)
                while (badNetwork.size >= 5) {
                    // badNetwork.pollLast()
                    // badNetwork.removeAt(badNetwork.size)
                    badNetwork.removeLast()
                }
                badNetwork.add(BadNetworkData())
                // badNetwork.push(BadNetwokData())
                // modifyFinish.set(true)
            }
        }

    }


    private val sdkMgtEventListener = object : SDKMgtEventListener {

        override fun onMgtMuteAudioEvent() {
            Log.e("CallActivityA", "onMgtMuteAudioEvent ${Thread.currentThread()}")
            dbyViewModel.mic(false)

            lifecycleScope.launch {
                toast("收到会控消息，正在静音")
            }
        }

        override fun onMgtMuteCameraEvent() {
            Log.e("CallActivityA", "onMgtMuteCameraEvent ${Thread.currentThread()}")
            dbyViewModel.camera(false)

            lifecycleScope.launch {
                toast("收到会控消息，正在关闭关闭摄像头")
            }
        }

        override fun onMgtMuteShareContentEvent() {
            MyLog.logD(MyLog.CALL_ACTIVITY_A_MODEL, "CallActivityA::onMgtMuteShareContentEvent: dbyViewModel.shareScreen:${dbyViewModel.shareScreen.value}  ")
            // 关闭hdmi
            if (dbyViewModel.shareScreen.value == AVDevice.HDMI_RES) {
                MyLog.logD(MyLog.HDMI_CAMERA_SEND_MODEL, "CallActivityA::onMgtMuteShareContentEvent:  dbyViewModel.hdmi  ")
                dbyViewModel.hdmi(false)
            }

            // 关闭wifi-camera
            if (dbyViewModel.shareScreen.value == AVDevice.WIFI_RES) {
                RxBus.get().post(RxConstant.RES_VIDEO_PUB_NOTIFY, false)
            }

            lifecycleScope.launch {
                toast("收到会控消息，正在关闭屏幕共享")
            }

        }

    }

    // private val muteAll = arrayListOf<String>()

    private fun stopNetSpeedTimer() {
        handler.removeCallbacksAndMessages(null)
        mNetSpeedTimer?.stopSpeedTimer()
        mNetSpeedTimer = null
    }

    override fun onDestroy() {
        super.onDestroy()
        stopNetSpeedTimer()

        RoomClientRepository.setMgtEventListener(null)
        RoomClientRepository.setNetworkQualityListener(null)

        MyLog.logD(MyLog.CALL_ACTIVITY_A_MODEL, "CallActivityA::onDestroy ")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_call_a)

        lifecycle.addObserver(HideSystemUILifecycleAware())

        setSupportActionBar(toolbar)

        appBarConfiguration = AppBarConfiguration.Builder()
                .setFallbackOnNavigateUpListener {
                    finish()
                    true
                }
                .build()

        navController = Navigation.findNavController(this, R.id.nav_host_fragment)

        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

        supportActionBar?.hide()


        //创建NetSpeedTimer实例
        mNetSpeedTimer = NetSpeedTimer(this, NetSpeed(), handler).setDelayTime(500).setPeriodTime(500)
        //在想要开始执行的地方调用该段代码
        mNetSpeedTimer?.startSpeedTimer()

        RoomClientRepository.setMgtEventListener(sdkMgtEventListener)
        RoomClientRepository.setNetworkQualityListener(networkQualityListener)

        dbyViewModel.join().observe(this, Observer { roomId ->
            Log.e("CallActivity", "roomId: $roomId")

            if (roomId == null) {
//                FIleManager.close()
                logger.info(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(Date())
                        + " CallActivityA::onCreate destroy $roomId")
                if (dbyViewModel.shareScreen.value == AVDevice.HDMI_RES) {
                    dbyViewModel.showHDMIView(false)
                } else if (dbyViewModel.shareScreen.value == AVDevice.WIFI_RES) {
                    dbyViewModel.showWiFiView(false)
                }

                SendAudioUtil.getInstance().clear()
                ScreenPushManager.getInstance().close()
                CameraHandle.getInstance().releaseCamera()
                HDMIHandle.getInstance().stopCamera()
                WifiCamera.getInstance().release()

                finish()
            } else {
//                FIleManager.create()
                // mDbyEngine.joinChannel(roomId, realUserId, realUserId)
                // mDbyEngine.recovery()
            }
        })



        lifecycleScope.launch {
            while (true) {
                // readyFinish.set(false)
                /*while (!modifyFinish.get()) {
                    delay(100)
                }*/
                val array = badNetwork.filter {

                    val delta = System.currentTimeMillis() - it.time

                    val b = (delta < 11 * 1000)

                    Log.e("CallActivityA", "badNetwork: $it, delta: $delta")

                    b
                }
                // readyFinish.set(true)
                if (array.size >= 4) {
                    checkBadNetWork++
                    if (checkBadNetWork >= 12) {
                        logger.info(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(Date()) + " CallActivityA::onCreate badNetwork AutoHangup-----多贝挂断")
//                        toast("当前网络状况差，通话即将结束~~~")
//                        dbyViewModel.join(null)
//                        RoomClientRepository.hangup()
                    } else {
                        toast("当前通话质量不佳~~~")
                    }

                } else {
                    checkBadNetWork = 0
                }
                // muteAll.clear()
                delay(10 * 1000)
            }
        }
    }


    override fun onResume() {
        super.onResume()
        IPUtils.SystemProperties.init();
        IPUtils.SystemProperties.set("persist.power.enable", "true");
    }

    override fun onPause() {
        super.onPause()
        IPUtils.SystemProperties.set("persist.power.enable", "false");
    }

    override fun onStop() {
        super.onStop()


    }


    override fun handleMessage(msg: Message?): Boolean {
        if (msg!!.what == NetSpeedTimer.NET_SPEED_TIMER_DEFAULT) {
            val speed = msg.obj as String
            lifecycleScope.launch {
                dbyNetworkViewModel.setSpeed(speed)
            }
        }
        return false
    }

    override fun onSupportNavigateUp(): Boolean { // Allows NavigationUI to support proper up navigation or the drawer layout
        // drawer menu, depending on the situation.
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }

    companion object {

        fun open(context: Context, call: Call) {
            if (!RoomClientRepository.connected()) return
            val intent = Intent(context, CallActivityA::class.java)
            intent.putExtra(CallConst.CALL_POJO, call)
            context.startActivity(intent)
        }

        fun open(context: Context, sessionContext: SessionContext) {
            val intent = Intent(context, CallActivityA::class.java)
            intent.putExtra(CallConst.NOTIFY_INFO, sessionContext)
            context.startActivity(intent)
        }
    }

    private val badNetwork = CopyOnWriteArrayList<BadNetworkData>()

    data class BadNetworkData(val time: Long = System.currentTimeMillis())
}
